package com.yuan.base.utils;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;

import com.yuan.base.framework.BaseAppContext;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;


/**
 * 图片处理相关类
 */
public class ImageUtil {

	private static final String TAG = "ImageUtil";

	/**
	 * @param bmp     获取的bitmap数据
	 * @param picName 自定义的图片名
	 */
	public static void saveBmp2Gallery(Bitmap bmp, String picName) {

		String fileName = null;
		//系统相册目录
		String galleryPath = Environment.getExternalStorageDirectory()
				+ File.separator + Environment.DIRECTORY_DCIM
				+ File.separator + "Camera" + File.separator;


		// 声明文件对象
		File file = null;
		// 声明输出流
		FileOutputStream outStream = null;

		try {
			// 如果有目标文件，直接获得文件对象，否则创建一个以filename为名称的文件
			file = new File(galleryPath, picName + ".jpg");

			// 获得文件相对路径
			fileName = file.toString();
			// 获得输出流，如果文件中有内容，追加内容
			outStream = new FileOutputStream(fileName);
			bmp.compress(Bitmap.CompressFormat.JPEG, 90, outStream);

		} catch (Exception e) {
			e.getStackTrace();
		} finally {
			try {
				if (outStream != null) {
					outStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//通知相册更新
		MediaStore.Images.Media.insertImage(BaseAppContext.getInstance().getContentResolver(), bmp, fileName, null);
		Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		Uri uri = Uri.fromFile(file);
		intent.setData(uri);
		BaseAppContext.getInstance().sendBroadcast(intent);

		UIUtil.showToast("图片保存成功");

	}

	//-----------------------------------------整理后的新api------------------------------------------

	/**
	 * 压缩图片到指定尺寸
	 */
	public static String resizeImageSize(String oldPath, String newPath, int WidthOrHeight) {
		return resizeImage(oldPath, newPath, 0, WidthOrHeight);
	}

	/**
	 * 压缩图片质量到指定大小
	 * @param imageSize 单位：kb
	 */
	public static String resizeImageQuality(String oldPath, String newPath, int imageSize) {
		return resizeImage(oldPath, newPath, imageSize, 0);
	}

	/**
	 * 图片压缩能够同时压缩质量和图片尺寸
	 * * @param imageSize 单位：kb
	 */
	public static String resizeImage(String oldPath, String newPath, int imageSize, int WidthOrHeight) {
		if (TextUtils.isEmpty(oldPath) || TextUtils.isEmpty(newPath))
			return "";

		Bitmap bitmap = BitmapUtil.getBitmapFromPath(oldPath);
		if (bitmap == null) {
			return oldPath;
		}
		// 压缩尺寸
		if (WidthOrHeight > 0) {
			int bitmapWidth = bitmap.getWidth();
			int bitmapHeight = bitmap.getHeight();
			if (bitmapWidth > WidthOrHeight || bitmapHeight > WidthOrHeight) {
				// 原始图片的高宽
				int[] cur_img_size = new int[]{bitmapWidth, bitmapHeight};
				// 计算原始图片缩放后的宽高
				int[] new_img_size = scaleImageSize(cur_img_size, WidthOrHeight);
				bitmap = Bitmap.createScaledBitmap(bitmap, new_img_size[0], new_img_size[1], true);
			}
		}
		// 压缩质量
		if (imageSize > 0) {
			// imageSize 单位：kb
//			bitmap = compressImage(bitmap, imageSize);
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
			int options = 100;
			while (stream.toByteArray().length / 1024 > imageSize) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
				stream.reset();// 重置baos即清空baos
				bitmap.compress(Bitmap.CompressFormat.JPEG, options, stream);// 这里压缩options%，把压缩后的数据存放到baos中
				options -= 10;// 每次都减少10
			}
			if (!FileUtil.createOrExistsFile(newPath)) return oldPath;
			FileOutputStream fos = null;
			try {
				fos = new FileOutputStream(newPath);
				stream.writeTo(fos);
				stream.flush();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				CloseUtil.closeIO(stream, fos);
			}
		} else {
			// 保存图片
			if (saveImage(bitmap, newPath)) {
				return oldPath;
			}
		}
		return newPath;
	}

	public static boolean saveImage(Bitmap src, String path) {
		if (src == null || !FileUtil.createOrExistsFile(path)) return false;
		boolean ret = false;
		BufferedOutputStream stream = null;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(path);
			stream = new BufferedOutputStream(fos);
			ret = src.compress(Bitmap.CompressFormat.JPEG, 100, stream);
			stream.flush();
		} catch (Exception e) {
			e.printStackTrace();
			Log.e("ImageUtil", "保存图片时出错:" + e.getMessage());
			return false;
		} finally {
			CloseUtil.closeIO(stream, fos);
			src.recycle();
		}
		return ret;
	}

	/**
	 * 计算缩放图片的宽高
	 * @param img_size
	 * @param square_size
	 */
	public static int[] scaleImageSize(int[] img_size, int square_size) {
		if (img_size[0] <= square_size && img_size[1] <= square_size)
			return img_size;
		double ratio = square_size / (double) Math.max(img_size[0], img_size[1]);
		return new int[]{(int) (img_size[0] * ratio), (int) (img_size[1] * ratio)};
	}

	/**
	 * 调整拍照图片的旋转
	 */
	public static String handleRotateRePath(String path) {
		//获取图片的旋转角度，有些系统把拍照的图片旋转了，有的没有旋转
		int degree = readPictureDegree(path);
		//处理旋转
		Bitmap bitmap;
		if (degree != 0) {
			bitmap = BitmapUtil.rotaingImageView(degree, BitmapUtil.getBitmapFromPath(path));
			File f = new File(path);
			try {
				FileOutputStream out = new FileOutputStream(f);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return path;
	}

	/**
	 * 获取图片的旋转角度
	 * @param path 文件路径
	 */
	public static int readPictureDegree(String path) {
		int degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
				case ExifInterface.ORIENTATION_ROTATE_90:
					degree = 90;
					break;
				case ExifInterface.ORIENTATION_ROTATE_180:
					degree = 180;
					break;
				case ExifInterface.ORIENTATION_ROTATE_270:
					degree = 270;
					break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return degree;
	}

	//-----------------------------------------未整理api------------------------------------------

	/**
	 * 按比例压缩到指定宽高的图片
	 */
	public static String getReSizeImagePath(String oPath, String thumbfilePath, String ext, int WidthOrHeight) {
		Date d1 = new Date();
		if (TextUtils.isEmpty(oPath))
			return "";
		File file = new File(thumbfilePath);
		try {
			file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 压缩图片
		Bitmap bitmap = BitmapUtil.getBitmapFromPath(oPath);
		// 原始图片的高宽
		int[] cur_img_size = new int[]{bitmap.getWidth(), bitmap.getHeight()};
		// 计算原始图片缩放后的宽高
		int[] new_img_size = scaleImageSize(cur_img_size, WidthOrHeight);
		bitmap = BitmapUtil.zoom(bitmap, new_img_size[0], new_img_size[1]);
		boolean isSuccess = ImageUtil.saveBitmapFile(bitmap, thumbfilePath, ext);
		if (isSuccess) {
			Log.d(TAG, thumbfilePath);
			Date d2 = new Date();
			LogUtil.d("------" + (d2.getTime() - d1.getTime()));
			return thumbfilePath;
		}
		return oPath;
	}

	public static void createImageThumbnail(String largeImagePath, String thumbfilePath, int square_size, int quality) throws IOException {
		Bitmap cur_bitmap = BitmapUtil.getBitmapFromPath(largeImagePath);
		if (cur_bitmap == null)
			return;
		// 原始图片的高宽
		int[] cur_img_size = new int[]{cur_bitmap.getWidth(), cur_bitmap.getHeight()};
		// 计算原始图片缩放后的宽高
		int[] new_img_size = scaleImageSize(cur_img_size, square_size);
		// 生成缩放后的bitmap
		Bitmap thb_bitmap = BitmapUtil.zoom(cur_bitmap, new_img_size[0], new_img_size[1]);
		// 生成缩放后的图片文件
		ImageUtil.saveBitmapFile(thb_bitmap, thumbfilePath, null);
	}

	/**
	 * 写图片文件到SD卡
	 * @throws IOException
	 */
	public static void saveImageToSD(String filePath, Bitmap bitmap, int quality) throws IOException {
		if (bitmap != null) {
			File file = new File(filePath.substring(0, filePath.lastIndexOf(File.separator)));
			if (!file.exists()) {
				file.mkdirs();
			}
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
			bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
			bos.flush();
			bos.close();
		}
	}

	/**
	 * 将Bitmap文件保存为文件路径下
	 */
	public static boolean saveBitmapFile(Bitmap bm, String imagePath, String type) {
		if (imagePath == null || imagePath.equals(""))
			return false;
		if (bm == null)
			return false;
		File f = new File(imagePath);
		if (!f.exists())
			try {
				f.createNewFile();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		BufferedOutputStream stream = null;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(f);
			stream = new BufferedOutputStream(fos);
			if (type != null && type.equals("png")) {
				bm.compress(Bitmap.CompressFormat.PNG, 80, stream);
			} else {
				bm.compress(Bitmap.CompressFormat.JPEG, 80, stream);
			}
			stream.flush();
		} catch (Exception e) {
			e.printStackTrace();
			Log.e("ImageUtil", "压缩图片时出错:" + e.getMessage());
			return false;
		} finally {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (!bm.isRecycled()) {
				bm.recycle();
			}
		}
		return true;
	}


//	public static Bitmap getImage(String fileName) {
//		FileInputStream stream = null;
//		try {
//			stream = new FileInputStream(fileName);
//			FileDescriptor fd = stream.getFD();
//			BitmapFactory.Options options = new BitmapFactory.Options();
//			options.inSampleSize = 1;
//			options.inJustDecodeBounds = true;
//			BitmapFactory.decodeFileDescriptor(fd, null, options);
//			if (options.mCancel || options.outWidth == -1
//					|| options.outHeight == -1) {
//				return null;
//			}
//			// 1.换算合适的图片缩放值，以减少对JVM太多的内存请求。
//			options.inSampleSize = computeSampleSize(options.outWidth, options.outHeight);
//			options.inJustDecodeBounds = false;
//
//			options.inDither = false;
//			options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//
//			// 2. inPurgeable 设定为 true，可以让java系统, 在内存不足时先行回收部分的内存
//			options.inPurgeable = true;
//			// 与inPurgeable 一起使用
//			options.inInputShareable = true;
//
//			try {
//				// 4. inNativeAlloc 属性设置为true，可以不把使用的内存算到VM里
//				BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options, true);
//			} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) {
//				e.printStackTrace();
//			}
//			// 5. 使用decodeStream 解码，则利用NDK层中，利用nativeDecodeAsset（）
//			// 进行解码，不用CreateBitmap
//			return BitmapFactory.decodeStream(stream, null, options);
//
//		} catch (IOException ex) {
//			Log.e(TAG, "", ex);
//		} catch (OutOfMemoryError oom) {
//			Log.e(TAG, "Unable to decode file " + fileName + ". OutOfMemoryError.", oom);
//		} finally {
//			try {
//				if (stream != null) {
//					stream.close();
//				}
//			} catch (IOException ex) {
//				Log.e(TAG, "", ex);
//			}
//		}
//		return null;
//	}


	/**
	 * 组合图片和源图片
	 * @param src       源图片
	 * @param watermark 水印图片
	 * @return 合成的图片
	 */
	public static Bitmap addWatermark(Bitmap src, Bitmap watermark) {
		// 另外创建一张图片
		Bitmap newBitMap = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
		Canvas canvas = new Canvas(newBitMap);
		canvas.drawBitmap(src, 0, 0, null);// 在 0，0坐标开始画入原图片src
		canvas.drawBitmap(watermark, src.getWidth() - watermark.getWidth() + 5, src.getHeight() - watermark.getHeight() + 5, null);

		canvas.save();
		canvas.restore();

		watermark.recycle();
		return newBitMap;
	}

	/**
	 * 生成时间文字水印图层；
	 */
	public static Bitmap makeTextBitMap(int w, int h, String text) {
		Bitmap bitMap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitMap);
		Paint p = new Paint();
		String familyName = "宋体";
		Typeface typeface = Typeface.create(familyName, Typeface.BOLD);
		p.setColor(Color.RED);
		p.setTypeface(typeface);
		p.setTextSize(22);
		canvas.drawText(text, 0, 120, p);
		return bitMap;
	}
}
